﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NPMonitor.Implementation;
using System.Threading;

namespace NPMonitor.Launcher
{
    public partial class MainForm : Form
    {
        #region Private Members

        NPMonitor.Service monitorService;

        System.Timers.Timer clockTimer = new System.Timers.Timer(1000); // 1 seconds

        #endregion

        #region Methods

        void service_Notify(object sender, NotificationEventArgs e)
        {
            SetText(e.Message);
        }

        void monitorService_OnConnectionStatusChange(object sender, ConnectionStatusChangeEventArgs e)
        {
            bool isFiddlerServiceStarted = Fiddler.FiddlerApplication.IsStarted();

            if (e.CurrentStatus == ConnectionStatus.Online)
            {
                if (!isFiddlerServiceStarted)
                {
                    FiddlerService.Instance.Start();
                }
            }
            else if (e.CurrentStatus == ConnectionStatus.Offline)
            {
                if (isFiddlerServiceStarted)
                {
                    FiddlerService.Instance.Stop();
                }
            }

            if (!this.IsDisposed)
            {
                tsslConnStatus.Text = e.CurrentStatus.ToString();
            }
        }

        void monitorService_OnServiceStatusChange(object sender, ServiceStatusChangeEventArgs e)
        {
            RefreshByServiceStatus(e.CurrentStatus);

            tsslServiceStatus.Text = e.CurrentStatus.ToString();
        }

        delegate void SetTextCallback(string text);

        private void SetText(string text)
        {
            try
            {
                if (this.lblMessage.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetText);
                    this.Invoke(d, new object[] { text });
                }
                else
                {
                    uint runningJobsCount = monitorService.RunningJobsCount;
                    if (runningJobsCount > 0)
                    {
                        this.lblMessage.Text = string.Format("Executing Jobs : {0}\r\n{1}", monitorService.RunningJobsCount, text);
                    }
                    else
                    {
                        this.lblMessage.Text = text;
                    }

                    this.lblMessage.Refresh();

                    Application.DoEvents();
                }
            }
            catch { }
        }

        private void RefreshByServiceStatus(ServiceStatus serviceStatus)
        {
            switch (serviceStatus)
            {
                case ServiceStatus.Running:
                    startToolStripMenuItem.Enabled = false;
                    pauseToolStripMenuItem.Enabled = true;
                    resumeToolStripMenuItem.Enabled = false;
                    stopToolStripMenuItem.Enabled = true;
                    break;
                case ServiceStatus.Paused:
                    startToolStripMenuItem.Enabled = false;
                    pauseToolStripMenuItem.Enabled = false;
                    resumeToolStripMenuItem.Enabled = true;
                    stopToolStripMenuItem.Enabled = true;
                    break;
                case ServiceStatus.Stopping:
                    startToolStripMenuItem.Enabled = false;
                    pauseToolStripMenuItem.Enabled = false;
                    resumeToolStripMenuItem.Enabled = false;
                    stopToolStripMenuItem.Enabled = false;
                    break;
                case ServiceStatus.Stopped:
                    startToolStripMenuItem.Enabled = false;
                    if (monitorService != null)
                    {
                        if (monitorService.ConnectionStatus == ConnectionStatus.Online)
                        {
                            startToolStripMenuItem.Enabled = true;
                        }
                    }
                    pauseToolStripMenuItem.Enabled = false;
                    resumeToolStripMenuItem.Enabled = false;
                    stopToolStripMenuItem.Enabled = false;
                    break;
            }
        }

        #endregion

        public MainForm(NPMonitor.Service service)
        {
            InitializeComponent();

            this.monitorService = service;

            this.clockTimer.Interval = 1000;
            this.clockTimer.Elapsed += new System.Timers.ElapsedEventHandler(clockTimer_Elapsed);
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            RefreshByServiceStatus(ServiceStatus.Stopped);

            this.monitorService.Notify += new EventHandler<NotificationEventArgs>(service_Notify);
            this.monitorService.OnServiceStatusChange += new EventHandler<ServiceStatusChangeEventArgs>(monitorService_OnServiceStatusChange);
            this.monitorService.OnConnectionStatusChange += new EventHandler<ConnectionStatusChangeEventArgs>(monitorService_OnConnectionStatusChange);

            this.clockTimer.Start();
            this.monitorService.Start();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;

                string infoMessage = "Closing window doesn't close the service, please right click the notify icon and click the exit if you want to close NPMonitor service";
                notifyIcon.ShowBalloonTip(5, "Info", infoMessage, ToolTipIcon.Info);

                this.Hide();
            }
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.notifyIcon.Visible = true;
            }
        }

        void clockTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            clockTimer.Stop();

            Thread thread = new Thread(() =>
            {
                try
                {
                    if (Helpers.Utils.IsServerTimeAvaliable)
                    {
                        DateTime serverTime = Helpers.Utils.CurrentServerUtcTime;

                        if (!this.IsDisposed)
                        {
                            this.Invoke(
                                new Action(() =>
                                {
                                    tsslblServerTime.Text = String.Format("Server Time: {0} {1}  ", serverTime, serverTime.DayOfWeek);
                                })
                            );
                        }
                    }
                }
                finally
                {
                    clockTimer.Start();
                }
            });

            thread.Start();
        }

        private void notifyIcon_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Show();

                WindowState = FormWindowState.Normal;//窗体恢复正常
            }
        }

        private void startToolStripMenuItem_Click(object sender, EventArgs e)
        {
            monitorService.Start();
        }

        private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            monitorService.Pause();
        }

        private void stopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // monitorService.Stop(true);
            monitorService.Stop(false);
        }

        private void resumeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            monitorService.Resume();
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SetText("Closing");

            clockTimer.Stop();  // stop clock timer here, otherwise clockTimer will keep alive

            if (monitorService != null)
            {
                // monitorService.Stop(true);
                monitorService.Stop(false);
            }

            bool isFiddlerServiceStarted = Fiddler.FiddlerApplication.IsStarted();

            if (isFiddlerServiceStarted)
            {
                FiddlerService.Instance.Stop();
            }

            Application.Exit();
        }
    }
}
